﻿using Basic.FormDAL;
using Basic.FormModel.DB;
using Basic.FormModel.PageLayout;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.PageLayout.Model;
using WeDonekRpc.Helper;

namespace Basic.FormCollect.lmpl
{
    internal class CustomPageLayoutCollect : ICustomPageLayoutCollect
    {
        private readonly PageControlType[] _FormControlType = new PageControlType[]
        {
            PageControlType.指标图,
            PageControlType.统计表,
            PageControlType.图表,
            PageControlType.明细表
        };
        private readonly ICustomPageLayoutDAL _BasicDAL;

        public CustomPageLayoutCollect ( ICustomPageLayoutDAL basicDAL )
        {
            this._BasicDAL = basicDAL;
        }

        public long Add ( PageLayoutAddDto data )
        {
            return this._BasicDAL.Add(data);
        }

        public void SaveSort ( Dictionary<long, int> sort )
        {
            this._BasicDAL.SaveSort(sort);
        }
        public void Delete ( DBCustomPageLayout sour )
        {
            this._BasicDAL.Delete(sour.Id);
        }

        public DBCustomPageLayout Get ( long id )
        {
            return this._BasicDAL.Get(id);
        }

        public Result Get<Result> ( long id ) where Result : class, new()
        {
            return this._BasicDAL.Get<Result>(id);
        }

        public Result[] Gets<Result> ( long pageId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.PageId == pageId, "Sort");
        }

        public bool Set ( DBCustomPageLayout layout, PageLayoutSet set )
        {
            return this._BasicDAL.Update(layout, set);
        }
        public long[] GetChildrenId ( long pageId, long parentId )
        {
            var list = this._BasicDAL.Gets(a => a.PageId == pageId && a.ParentId != 0, a => new
            {
                a.Id,
                a.ParentId,
                a.ControlType
            });
            if ( list.IsNull() )
            {
                return null;
            }
            long[] pids = list.Convert(c => c.ControlType == PageControlType.容器 && c.ParentId == parentId, c => c.Id);
            if ( pids.IsNull() )
            {
                return list.Convert(a => a.ParentId == parentId, a => a.Id);
            }
            List<long> children = list.Where(a => a.ParentId == parentId).Select(a => a.Id).ToList();
            do
            {
                var t = this._BasicDAL.Gets(a => pids.Contains(a.ParentId), a => new
                {
                    a.Id,
                    a.ControlType
                });
                t.ForEach(c =>
                {
                    children.Add(c.Id);
                });
                pids = t.Convert(c => c.ControlType == PageControlType.容器, c => c.Id);
            } while ( pids.Length > 0 );
            return children.ToArray();
        }
        public PageLayoutDatum[] GetChildren ( long pageId, long parentId )
        {
            PageLayoutDatum[] list = this._BasicDAL.Gets<PageLayoutDatum>(a => a.PageId == pageId && a.ParentId != 0, "Sort");
            if ( list.IsNull() )
            {
                return list;
            }
            long[] pids = list.Convert(c => c.ControlType == PageControlType.容器 && c.ParentId == parentId, c => c.Id);
            if ( pids.IsNull() )
            {
                return list.FindAll(a => a.ParentId == parentId);
            }
            List<PageLayoutDatum> children = list.Where(a => a.ParentId == parentId).ToList();
            do
            {
                PageLayoutDatum[] t = this._BasicDAL.Gets<PageLayoutDatum>(a => pids.Contains(a.ParentId));
                children.AddRange(t);
                pids = t.Convert(c => c.ControlType == PageControlType.容器, c => c.Id);
            } while ( pids.Length > 0 );
            return children.ToArray();
        }

        public bool Move ( DBCustomPageLayout layout, long parentId )
        {
            if ( layout.ParentId == parentId )
            {
                return false;
            }
            layout.ParentId = parentId;
            return this._BasicDAL.Update(layout, new string[] { "ParentId" });
        }

        public void Clear ( long[] ids )
        {
            this._BasicDAL.Delete(ids);
        }

        public Result[] GetFormItem<Result> ( long pageId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.PageId == pageId && this._FormControlType.Contains(a.ControlType));
        }
    }
}
